#pragma once

#include <rtl/base.h>

typedef enum
{
    NORMAL_BOOT = 0,
    META_BOOT = 1,
    RECOVERY_BOOT = 2,
    SW_REBOOT = 3,
    FACTORY_BOOT = 4,
    ADVMETA_BOOT = 5,
    ATE_FACTORY_BOOT = 6,
    ALARM_BOOT = 7,
    FASTBOOT = 99,

    DOWNLOAD_BOOT = 100,
    UNKNOWN_BOOT
} BOOT_MODE;

typedef enum
{
    BOOT_REASON_POWER_KEY = 0,
    BOOT_REASON_USB,
    BOOT_REASON_RTC,
    BOOT_REASON_WDT,
    BOOT_REASON_WDT_BY_PASS_PWK,
    BOOT_REASON_TOOL_BY_PASS_PWK,
    BOOT_REASON_2SEC_REBOOT,
    BOOT_REASON_UNKNOWN,
    BOOT_REASON_KERNEL_PANIC,
    BOOT_REASON_WDT_SW,
    BOOT_REASON_WDT_HW
} BOOT_REASON;

#define ATAG_TYPE_BOOT_REASON 0x88610001
#define ATAG_TYPE_BOOT_MODE 0x88610002
#define ATAG_TYPE_META_COM 0x88610003
#define ATAG_TYPE_LOG_COM 0x88610004
#define ATAG_TYPE_MEM 0x88610005
#define ATAG_TYPE_MD_INFO 0x88610006
#define ATAG_TYPE_BOOT_TIME 0x88610007
#define ATAG_TYPE_DA_INFO 0x88610008
#define ATAG_TYPE_SEC_INFO 0x88610009
#define ATAG_TYPE_PART_NUM 0x8861000A
#define ATAG_TYPE_PART_INFO 0x8861000B
#define ATAG_TYPE_EFLAG 0x8861000C
#define ATAG_TYPE_DDR_RESERVE 0x8861000D
#define ATAG_TYPE_DRAM_BUF 0x8861000E
#define ATAG_TYPE_PTP 0x88610010
#define ATAG_TYPE_SRAM_INFO 0x88610012
#define ATAG_TYPE_EXTBUCK_FAN53526 0x88610014

typedef struct _ATAG_HEADER
{
    UINT32 Size;
    UINT32 Tag;
} ATAG_HEADER, *PATAG_HEADER;

typedef struct _ATAG_BOOT_REASON
{
    ATAG_HEADER Header;
    UINT32 BootReason;
} ATAG_BOOT_REASON, *PATAG_BOOT_REASON;

typedef struct _ATAG_BOOT_MODE
{
    ATAG_HEADER Header;
    UINT32 BootMode;
} ATAG_BOOT_MODE, *PATAG_BOOT_MODE;

typedef struct _ATAG_META_COM
{
    ATAG_HEADER Header;
    UINT32 MetaComType;
    UINT32 MetaComId;
    UINT32 MetaUartPort;
} ATAG_META_COM, *PATAG_META_COM;

typedef struct _ATAG_LOG_COM
{
    ATAG_HEADER Header;
    UINT32 LogPort;
    UINT32 LogBaudrate;
    UINT32 LogEnable;
} ATAG_LOG_COM, *PATAG_LOG_COM;

typedef struct _MBLOCK
{
    UINT64 Start;
    UINT64 Size;
    UINT32 Rank;
} MBLOCK, *PMBLOCK;

typedef struct _MBLOCK_INFO
{
    UINT32 MBlockNum;
    MBLOCK MBlock[128];
} MBLOCK_INFO, *PMBLOCK_INFO;

typedef struct _MEMORY_DESCRIPTOR
{
    UINT64 Start;
    UINT64 Size;
} MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR;

typedef struct _DRAM_INFO
{
    UINT32 RankNum;
    MEMORY_DESCRIPTOR RankInfo[4];
} DRAM_INFO, *PDRAM_INFO;

typedef struct _ATAG_MEM
{
    ATAG_HEADER Header;
    UINT32 DramRankNum;
    UINT32 DramRankSize[4];
    MBLOCK_INFO MBlockInfo;
    DRAM_INFO DramInfo;
    MEMORY_DESCRIPTOR LcaReservedMemory;
    MEMORY_DESCRIPTOR TeeReservedMemory;
} ATAG_MEM, *PATAG_MEM;

typedef struct _ATAG_MD_INFO
{
    ATAG_HEADER Header;
    UINT32 MdType[4];
} ATAG_MD_INFO, *PATAG_MD_INFO;

typedef struct _ATAG_DA_INFO
{
    ATAG_HEADER Header;
    UINT32 Address;
    UINT32 Arg1;
    UINT32 Arg2;
    UINT32 Size;
    UINT32 SignatureSize;
} ATAG_DA_INFO, *PATAG_DA_INFO;

PATAG_HEADER AgpGetAtag(UINT32 Tag);